// 工具类型
/**
 * Partial<type>
 * 构造类型Type，并将它所有的属性设置为可选的。它的返回类型表示输入类型的所有子类型。
 * */
interface PersonType {
  name: string;
  age: number;
  sex: string;
}

type ManType = Partial<PersonType>;

let p: PersonType = {
  name: "",
  age: 0,
  sex: "",
};
//拥有PersonType所有类型，但都是非必须的
let m: ManType = {};
/**
 * Readonly<Type>
 */
type TestType = {
  name: string;
  age: number;
  sex: string;
};

let testType: TestType = {
  name: "1",
  age: 0,
  sex: "22",
};

testType.name = "张三";

type ReadonlyTestType = Readonly<TestType>;
let readonlyTestType: ReadonlyTestType = {
  name: "22",
  age: 0,
  sex: "33",
};
// readonlyTestType.name = '李四' //name是只读属性，无法修改

/**
 * Record<K,T>
 */
interface RecordTest1 {
  name: string;
  age: number;
}
type RecordTest2 = "zhangsan" | "lisi";

let testRecord: Record<RecordTest2, RecordTest1> = {
  zhangsan: {
    name: "",
    age: 0,
  },
  lisi: {
    name: "",
    age: 0,
  },
};
/**
 * Pick<Type,key>
 */
interface PickTest1 {
  name: string;
  age: number;
}
type PickTest2 = Pick<PickTest1, "name">; //选择其中的那么属性构成新的类型

let pickTest1: PickTest1 = {
  name: "",
  age: 0,
};

let pickTest2: PickTest2 = {
  name: "",
};
/**
 * omit<Type,key>
 */
interface OmitTest1 {
  name: string;
  age: number;
}
type OmitTest2 = Omit<PickTest1, "name">; //去除其中的那么属性构成新的类型

let omitTest1: OmitTest1 = {
  name: "",
  age: 0,
};

let omitTest2: OmitTest2 = {
  age: 0,
  //   name:'lisi'//name已经被去除
};

/**
 * Exclude<Type,key>
 */
type ExcludeTest1 = OmitTest1 | string | number;
type ExcludeTest2 = OmitTest1;
type ExcludeTest4 = string;
type ExcludeTest3 = Exclude<ExcludeTest1, ExcludeTest2>; //去除ExcludeTest1在ExcludeTest2中的属性构成新的类型
type ExcludeTest5 = Exclude<ExcludeTest1, ExcludeTest4>;

let excludeTest1: ExcludeTest1 = {
  name: "",
  age: 0,
};

let excludeTest2: ExcludeTest2 = {
  name: "",
  age: 0,
};

let excludeTest3: ExcludeTest3 = "22" || 12; //可以是number或者string
let excludeTest5: ExcludeTest5 = 12 || {
  name: "",
  age: 0,
}; //可以是number或者OmitTest1

/**
 * Extract<Type, Union>
 */
type Extractest1 = OmitTest1 | string | number;
type ExtractTest2 = OmitTest1;
type ExtractTest4 = string;
type ExtractTest3 = Extract<Extractest1, ExtractTest2>;
type ExtractTest5 = Extract<Extractest1, ExtractTest4>;

let extracTest3: ExtractTest3 = {
  name: "",
  age: 0,
};
let extracTest5: ExtractTest5 = "22";
/**
 * NonNullable
 */
type NonNullableTest1 = string | number | null;
type NonNullableTest2 = NonNullable<NonNullableTest1>;
/**
 * ConstructorParameters
 */
class ConstructorParametersTest1 {
  name1: string;
  age: number;
  constructor(name: string,age:number) {
    this.name1 = name;
    this.age = age;
  }
}
type ConstructorParametersTest2 = ConstructorParameters<typeof ConstructorParametersTest1>

let constructorParametersTest2:ConstructorParametersTest2 = ['dd',12]

type T2 = ReturnType<(() => number)>;  // {}